﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace QldtSdh.GUI.DaoTao
{
    using BLL;
    using DAL;
    using DAL.Models;
    using GUI.Utils;
    using GUI.Common;
    using Utils;

    public partial class UcLopHocPhan_ThoiKhoaBieu : QldtSdh.GUI.Common.BaseUserControl, IQuanLyLopHocPhan
    {
        private static Color NORMAL_BACKCOLOR = Color.White;
        private static Color SELECTED_BACKCOLOR = Color.LightSteelBlue;
        private static Color BUSY_NORMAL_BACKCOLOR = Color.Snow;
        private static Color BUSY_SELECTED_BACKCOLOR = Color.MistyRose;

        private bool _DoNotLoadThoiKhoaBieu = false;
        private bool _DoNotUpdateResourceViewer = false;

        private LopHocPhan _LopHocPhan;
        private List<LopHocPhan_PhanCongGiangDay> _ListLopHocPhan_PhanCongGiangDay;
        private List<PhongHoc> _ListPhongHoc;
        private DateTime _ThuHai;
        private DateTime _CN { get { return _ThuHai.AddDays(6).Add(new TimeSpan(23, 59, 59)); } }
        private Label[][] _Values;

        private Label _CurrentCell = null;
        public Label GetCurrentCell() { return _CurrentCell; }
        public void SetCurrentCell(Label label, bool doNotSetBackForFormResourceViewer = false)
        {
            if (_Values == null)
                return;
            _CurrentCell = label;
            if (label == null)
                return;
            foreach (var items in _Values)
                foreach (var item in items)
                {
                    if (label.Name == item.Name)
                    {
                        if (item.Name.Contains("8"))
                            item.BackColor = BUSY_SELECTED_BACKCOLOR;
                        else
                            item.BackColor = SELECTED_BACKCOLOR;
                    }
                    else
                    {
                        if (item.Name.Contains("8"))
                            item.BackColor = BUSY_NORMAL_BACKCOLOR;
                        else
                            item.BackColor = NORMAL_BACKCOLOR;
                    }
                }
            if (doNotSetBackForFormResourceViewer || !FormResourcesViewer.IsShowing)
                return;
            FormResourcesViewer.Instance.SetCurrentCell(label, true);
        }

        internal void SetCurrentCell(DateTime ngay, int buoi, bool doNotSetBackForFormResourceViewer = false)
        {
            var idxNgay = BizThoiKhoaBieu.GetIndexFromDOW(ngay.DayOfWeek);
            SetCurrentCell(_Values[buoi][idxNgay], doNotSetBackForFormResourceViewer);
        }

        public DateTime SelectedDate
        {
            get
            {
                int idx = -1;
                var currentCell = this.GetCurrentCell();
                if (currentCell == null)
                    return DateTime.Now;
                var currentName = currentCell.Name;
                if (currentName.Contains("2"))
                    idx = 0;
                else if (currentName.Contains("3"))
                    idx = 1;
                else if (currentName.Contains("4"))
                    idx = 2;
                else if (currentName.Contains("5"))
                    idx = 3;
                else if (currentName.Contains("6"))
                    idx = 4;
                else if (currentName.Contains("7"))
                    idx = 5;
                else if (currentName.Contains("8"))
                    idx = 6;
                return _ThuHai.AddDays(idx);
            }
            set
            {
                int buoi = 0;
                var cell = GetCurrentCell();
                if (cell != null)
                {
                    if (cell.Name.Contains("C"))
                        buoi = 1;
                    else if (cell.Name.Contains("T"))
                        buoi = 2;
                }
                var idx = BizThoiKhoaBieu.GetIndexFromDOW(value.DayOfWeek);
                SetThuHai(value, currentcell: _Values[buoi][idx]); // on SelectedDate
            }
        }

        private void SetThuHai(DateTime date, Label currentcell = null)
        {
            #region _ThuHai = ...(date);
            date = date.Date;
            _ThuHai = date.Subtract(new TimeSpan(BizThoiKhoaBieu.GetIndexFromDOW(date.DayOfWeek), 0, 0, 0));
            #endregion

            lblTuanHoc.Text = string.Format("Thứ hai {0} ÷ CN {1}", _ThuHai.ToString("dd/MM/yyyy"), _CN.ToString("dd/MM/yyyy"));

            #region Column headers
            lblCH2.Text = string.Format("Thứ 2\r\n{0}", _ThuHai.AddDays(0).ToString("dd/MM"));
            lblCH3.Text = string.Format("Thứ 3\r\n{0}", _ThuHai.AddDays(1).ToString("dd/MM"));
            lblCH4.Text = string.Format("Thứ 4\r\n{0}", _ThuHai.AddDays(2).ToString("dd/MM"));
            lblCH5.Text = string.Format("Thứ 5\r\n{0}", _ThuHai.AddDays(3).ToString("dd/MM"));
            lblCH6.Text = string.Format("Thứ 6\r\n{0}", _ThuHai.AddDays(4).ToString("dd/MM"));
            lblCH7.Text = string.Format("Thứ 7\r\n{0}", _ThuHai.AddDays(5).ToString("dd/MM"));
            lblCH8.Text = string.Format("CN\r\n{0}", _ThuHai.AddDays(6).ToString("dd/MM"));
            #endregion

            if (_DoNotLoadThoiKhoaBieu)
                return;
            NapDanhSachThoiKhoaBieu();

            if (_DoNotUpdateResourceViewer)
                return;
            if (FormResourcesViewer.IsShowing)
                FormResourcesViewer.Instance.SetThuHai(_ThuHai);

            if (currentcell != null)
                this.SetCurrentCell(currentcell);
        }

        public void HighlightAt(DateTime ngayHoc, int buoiHoc)
        {
            var newThuHai = _ThuHai = ngayHoc.Subtract(new TimeSpan(BizThoiKhoaBieu.GetIndexFromDOW(ngayHoc.DayOfWeek), 0, 0, 0));
            var newCurrentCell = _Values[buoiHoc][BizThoiKhoaBieu.GetIndexFromDOW(ngayHoc.DayOfWeek)];
            SetThuHai(newThuHai, newCurrentCell);
        }

        public UcLopHocPhan_ThoiKhoaBieu()
        {
            InitializeComponent();

            chkKiemTraDuLieuDaiHoc.Image = Program.KiemTraThoiKhoaBieuDaiHoc ? Properties.Resources.CHECKBOX_YES : Properties.Resources.CHECKBOX_NO;

            _Values = new Label[][] {
                new Label[]{ lbl2S, lbl3S, lbl4S, lbl5S, lbl6S, lbl7S, lbl8S },
                new Label[]{ lbl2C, lbl3C, lbl4C, lbl5C, lbl6C, lbl7C, lbl8C },
                new Label[]{ lbl2T, lbl3T, lbl4T, lbl5T, lbl6T, lbl7T, lbl8T }};

            _CurrentCell = lbl2S;

            chkXacNhanXoa.Tag = true;
        }

        public void SetLopHocPhan(LopHocPhan lopHocPhan)
        {
            if (_LopHocPhan != lopHocPhan)
            {
                FormLopHocPhan_ThoiKhoaBieu_KetQuaSaoChep.CloseIt();
            }

            _LopHocPhan = lopHocPhan;
            tsThoiKhoaBieu.Enabled = _LopHocPhan != null;
            chkChoPhepChinhSua.Enabled = _LopHocPhan != null;
            UpdateGuiByChophepChinhsuaState();
            using (var db = CEMS4UG_DHKHContext.GetContext())
            {
                _DoNotLoadThoiKhoaBieu = true;
                try
                {
                    LopKhoaNganh lopKhoaNganh = null;
                    if (_LopHocPhan != null)
                        lopKhoaNganh = BizLopKhoaNganh.GetByID(_LopHocPhan.MaLopKhoaNganhThamChieu);
                    string maCoSoDaoTaoGUID = lopKhoaNganh != null ? lopKhoaNganh.MaCoSoDaoTaoGUID : null;

                    // Nạp danh sách các phòng học
                    _ListPhongHoc = BizPhongHoc.GetList(maCoSoDaoTaoGUID, db);

                    // Nạp danh sách giảng viên được của lớp học phần
                    string maLopHocPhan = _LopHocPhan != null ? _LopHocPhan.MaLopHocPhanGUID : null;
                    _ListLopHocPhan_PhanCongGiangDay = BizPhanCongGiangDay.GetListGiangVienGiangDay(maLopHocPhan, db);

                    SetThuHai(BizThoiKhoaBieu.GetNgayHocDauTien(_LopHocPhan, db)); // on SetLopHocPhan()

                    HienThiTongSoBuoiDaPhan(db);
                }
                catch
                {

                }
                finally
                {
                    _DoNotLoadThoiKhoaBieu = false;
                }

                NapDanhSachThoiKhoaBieu();

                if (chkChoPhepChinhSua.Checked)
                    //FormResourcesViewer.ShowFor(this, this.SelectedGiangVien, this.SelectedPhongHoc, _ThuHai);
                    //FormResourcesViewer.ShowFor(this, this._LopHocPhan, _ThuHai);
                    FormResourcesViewer.ShowFor(this, this._LopHocPhan, _ListLopHocPhan_PhanCongGiangDay, _ListPhongHoc, _ThuHai);
                else
                    FormResourcesViewer.CloseIt();

                SetCurrentCell(_CurrentCell);
            }
        }

        private void HienThiTongSoBuoiDaPhan(CEMS4UG_DHKHContext db = null)
        {
            if (db == null)
                using (var db2 = CEMS4UG_DHKHContext.GetContext())
                    HienThiTongSoBuoiDaPhan(db2);
            else
            {
                string maLopHocPhanGUID = _LopHocPhan == null ? null : _LopHocPhan.MaLopHocPhanGUID;
                var soBuoiDaPhan = BizThoiKhoaBieu.GetSoBuoiDaPhan(maLopHocPhanGUID, db);
                lblThongKe.Text = string.Format("Tổng số buổi đã phân: {0} buổi", soBuoiDaPhan);
            }
        }

        private void NapDanhSachThoiKhoaBieu(bool andAlsoReloadLichBan = false)
        {
            var lstTKB = BizThoiKhoaBieu.GetList(_LopHocPhan, _ThuHai, _CN);
            for (int i = 0; i <= 6; i++)
                for (int j = 0; j <= 2; j++)
                {
                    _Values[j][i].Tag = _ThuHai.AddDays(i);
                    _Values[j][i].Text = "";
                }
            foreach (var x in lstTKB)
            {
                var buoiHoc = x.BuoiHoc;
                var thuTrongTuan = x.NgayHoc.DayOfWeek;
                var idx = BizThoiKhoaBieu.GetIndexFromDOW(thuTrongTuan);

                if (0 <= buoiHoc && buoiHoc <= 2)
                {
                    _Values[buoiHoc][idx].Text = x._Value;
                    _Values[buoiHoc][idx].Tag = x;
                }
                else
                    throw new Exception(string.Format("Lỗi: {0}", x.ToString()));
            }

            if (andAlsoReloadLichBan && FormResourcesViewer.IsShowing)
                FormResourcesViewer.Instance.NapDanhSachThoiKhoaBieu();
        }

        private void chkChoPhepChinhSua_CheckedChanged(object sender, EventArgs e)
        {
            UpdateGuiByChophepChinhsuaState();
        }

        private void UpdateGuiByChophepChinhsuaState()
        {
            if (chkChoPhepChinhSua.Checked)
            {
                miSaoChep.Enabled = miXoaTatCa.Enabled = miXoaTuan.Enabled = true;
                if (FormResourcesViewer.IsShowing == false)
                    FormResourcesViewer.ShowFor(this, _LopHocPhan, _ListLopHocPhan_PhanCongGiangDay, _ListPhongHoc, _ThuHai);
                chkKiemTraDuLieuDaiHoc.Visible = chkXacNhanXoa.Visible = true;
            }
            else
            {
                miSaoChep.Enabled = miXoaTatCa.Enabled = miXoaTuan.Enabled = false;
                FormResourcesViewer.CloseIt();
                FormLopHocPhan_ThoiKhoaBieu_KetQuaSaoChep.CloseIt();
                chkKiemTraDuLieuDaiHoc.Visible = chkXacNhanXoa.Visible = false;
            }
        }

        private void lbl2S_MouseClick(object sender, MouseEventArgs e)
        {
            this.SetCurrentCell(sender as Label);

            if (chkChoPhepChinhSua.Checked == false)
                return;

            if (string.IsNullOrEmpty(FormResourcesViewer.Instance.SelectedMaGiangVien) ||
                string.IsNullOrEmpty(FormResourcesViewer.Instance.SelectedMaPhongHoc))
                return;

            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                var oBuoi = sender as Label;
                if (string.IsNullOrEmpty(oBuoi.Text))
                {
                    // hiển thị menu set thời khoá biểu
                    tsmiChinhsua.Visible = false;
                    tsmiXoa.Visible = false;
                    tsmiBosung.Visible = true;
                }
                else
                {
                    // hiển thị menu xoá/thay đổi phòng học cho mục thời khoá biểu
                    tsmiChinhsua.Visible = true;
                    tsmiXoa.Visible = true;
                    tsmiBosung.Visible = false;
                }
                cmsMucThoikhoabieu.Show(Cursor.Position);
            }
        }

        private void lbl2S_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (sender != GetCurrentCell())
                this.SetCurrentCell(sender as Label);

            if (chkChoPhepChinhSua.Checked == false)
                return;

            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                Label lbl = sender as Label;
                if (lbl == null)
                    return;
                if (lbl.Tag is DateTime)
                    tsmiBosung_Click(null, null);
                else
                    tsmiChinhsua_Click(null, null);
            }
        }

        private void btnChuyenTuan_Click(object sender, EventArgs e)
        {
            if (sender == btnTuanTruoc)
                SetThuHai(_ThuHai.AddDays(-7)); // on navigate
            else if (sender == btnTuanKeTiep)
                SetThuHai(_ThuHai.AddDays(7)); // on navigate
            else if (sender == btnTuanDauTien)
                SetThuHai(BizThoiKhoaBieu.GetNgayHocDauTien(_LopHocPhan)); // on navigate
            else if (sender == btnTuanCuoiCung)
                SetThuHai(BizThoiKhoaBieu.GetNgayHocCuoiCung(_LopHocPhan)); // on navigate
        }

        private void tsmiXoa_Click(object sender, EventArgs e)
        {
            var currentCell = this.GetCurrentCell();
            if (currentCell == null)
                return;
            var tkb = currentCell.Tag as LopHocPhan_ThoiKhoaBieu;
            if (tkb == null)
                return;
            if ((bool)chkXacNhanXoa.Tag)
                if (!DialogUtils.Confirmed("Bạn có chắc chắn muốn xoá mục thời khoá biểu Buổi {0} ngày {1} không?", BizThoiKhoaBieu.GetStringOfBuoi(tkb.BuoiHoc),
                        BizThoiKhoaBieu.GetThuTrongTuan(tkb.NgayHoc.DayOfWeek), tkb.NgayHoc.ToString("dd/MM/yyyy")))
                    return;

            try
            {
                BizThoiKhoaBieu.DeleteThoiKhoaBieu(tkb.MaLopHocPhan_ThoiKhoaBieuGUID);
                NapDanhSachThoiKhoaBieu(andAlsoReloadLichBan: true);
                HienThiTongSoBuoiDaPhan();
            }
            catch (Exception exc)
            {
                DialogUtils.ShowErrorWithDefaultTitle("Không thể xoá mục thời khoá biểu Buổi {0} ngày {1}.\nChi tiết lỗi: {2}", BizThoiKhoaBieu.GetStringOfBuoi(tkb.BuoiHoc),
                        BizThoiKhoaBieu.GetThuTrongTuan(tkb.NgayHoc.DayOfWeek), tkb.NgayHoc.ToString("dd/MM/yyyy"), exc.Message);
            }
        }

        private void tsmiChinhsua_Click(object sender, EventArgs e)
        {
            var currentCell = this.GetCurrentCell();
            if (currentCell == null)
                return;
            var tkb = currentCell.Tag as LopHocPhan_ThoiKhoaBieu;
            if (tkb == null)
                return;

            var dlg = new FormLopHocPhan_ThoiKhoaBieu_ChiTiet(_LopHocPhan, tkb, _ListLopHocPhan_PhanCongGiangDay, _ListPhongHoc);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                NapDanhSachThoiKhoaBieu(andAlsoReloadLichBan: true);
            }
        }

        private void tsmiBosung_Click(object sender, EventArgs e)
        {
            //var giangVien = this.SelectedGiangVien;
            var maGiangVien = FormResourcesViewer.Instance.SelectedMaGiangVien;
            //giangVien == null ? null : giangVien.MaGiangVien;
            //var phongHoc = this.SelectedPhongHoc;
            var maPhongHoc = FormResourcesViewer.Instance.SelectedMaPhongHoc;
            //phongHoc == null ? null : phongHoc.MaPhongHoc;
            var currentCell = this._CurrentCell;
            int buoiHoc = currentCell.Name.EndsWith("S") ? 0 : (currentCell.Name.EndsWith("C") ? 1 : 2);
            DateTime ngayHoc = (DateTime)(currentCell.Tag);

            var dlg = new FormLopHocPhan_ThoiKhoaBieu_ChiTiet(
                _LopHocPhan, maGiangVien, maPhongHoc, ngayHoc, buoiHoc,
                _ListLopHocPhan_PhanCongGiangDay,
                _ListPhongHoc);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                NapDanhSachThoiKhoaBieu(andAlsoReloadLichBan: true);
                HienThiTongSoBuoiDaPhan();
            }
        }

        private void lblHienThiLichBan_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (chkChoPhepChinhSua.Checked)
            {
                if (FormResourcesViewer.IsShowing)
                    FormResourcesViewer.CloseIt();
                else
                    //FormResourcesViewer.ShowFor(this, this.SelectedGiangVien, this.SelectedPhongHoc, this._ThuHai);
                    FormResourcesViewer.ShowFor(this, _LopHocPhan, _ListLopHocPhan_PhanCongGiangDay, _ListPhongHoc, _ThuHai);
            }
        }

        private void lnkGoTo_Click(object sender, EventArgs e)
        {
            var dlg = new DialogGetDate(this.SelectedDate);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                // this.SelectedDate = dlg.SelectedDate; // on
                //var newThuHai = selectedDate.Subtract(new TimeSpan(BizThoiKhoaBieu.GetIndexFromDOW(selectedDate.DayOfWeek), 0, 0, 0));
                var selectedDate = dlg.SelectedDate;
                var currentBuoi = this._CurrentCell.Name.EndsWith("S") ? 0 : this._CurrentCell.Name.EndsWith("C") ? 1 : 2;
                SetThuHai(selectedDate, _Values[currentBuoi][BizThoiKhoaBieu.GetIndexFromDOW(selectedDate.DayOfWeek)]);
            }
        }

        private void miTKB_XemThongTinThongKe_Click(object sender, EventArgs e)
        {
            if (_LopHocPhan != null)
            {
                var frm = new FormLopHocPhan_ThoiKhoaBieu_ThongKe(_LopHocPhan);
                frm.ShowDialog();
            }
        }

        private void miTKB_XoaTuan_Click(object sender, EventArgs e)
        {
            if ((bool)chkXacNhanXoa.Tag == true)
                if (DialogUtils.Confirmed("Bạn có chắc chắn muốn xoá tất cả mục thời khoá biểu của lớp học phần trong tuần học này không?"))
                {
                    try
                    {
                        int n = BizThoiKhoaBieu.DeleteThoiKhoaBieu(_LopHocPhan, _ThuHai, _CN);
                        if (n > 0)
                        {
                            NapDanhSachThoiKhoaBieu(andAlsoReloadLichBan: true);
                            HienThiTongSoBuoiDaPhan();
                        }
                    }
                    catch (Exception exc)
                    {
                        DialogUtils.ShowErrorWithDefaultTitle("Không thể xoá dữ liệu thời khoá biểu của tuần học\n.Chi tiết lỗi: {0}", exc.Message);
                    }
                }
        }

        private void miTKB_XoaTatCa_Click(object sender, EventArgs e)
        {
            if ((bool)chkXacNhanXoa.Tag)
                if (DialogUtils.Confirmed("Bạn có chắc chắn muốn xoá tất cả mục thời khoá biểu của lớp học phần này không?"))
                {
                    try
                    {
                        int n = BizThoiKhoaBieu.DeleteThoiKhoaBieu(_LopHocPhan);
                        if (n > 0)
                        {
                            NapDanhSachThoiKhoaBieu(andAlsoReloadLichBan: true);
                            HienThiTongSoBuoiDaPhan();
                        }
                    }
                    catch (Exception exc)
                    {
                        DialogUtils.ShowErrorWithDefaultTitle("Không thể xoá dữ liệu thời khoá biểu của lớp học phần\n.Chi tiết lỗi: {0}", exc.Message);
                    }
                }
        }

        private void miTKB_SaoChep_Click(object sender, EventArgs e)
        {
            var frm = new FormLopHocPhan_ThoiKhoaBieu_SaoChep(_LopHocPhan, _ThuHai, _CN);
            if (frm.ShowDialog() == DialogResult.OK)
            {
                string st = string.Format("Sao chép tuần {0}÷{1} của lớp học phần {2} đến {3} tuần {4}",
                    _ThuHai.ToString("dd/MM"), _CN.ToString("dd/MM"), _LopHocPhan.TenLopHocPhan, frm.SoTuanSaoChep, frm.HuongSaoChep);
                FormLopHocPhan_ThoiKhoaBieu_KetQuaSaoChep.ShowKetQua(frm.ListOfKetQuaSaoChep, this, st);

                HienThiTongSoBuoiDaPhan();
            }
        }

        private void chkXacNhanXoa_Click(object sender, EventArgs e)
        {
            chkXacNhanXoa.Tag = !(bool)chkXacNhanXoa.Tag;
            chkXacNhanXoa.Image = (bool)chkXacNhanXoa.Tag ? Properties.Resources.CHECKBOX_YES : Properties.Resources.CHECKBOX_NO;
        }

        private void miTKB_In_Click(object sender, EventArgs e)
        {
            //
            //Thời khoá biểu giảng viên trong 1 học kỳ:
            //STT, Mã học phần, Tên học phần, Số TC, Số HV, Thứ, Buổi, MãPhòngHọc, NgàyĐầuTuầnCuảNgàyHọc
            //Sắp xếp tăng dần theo MãLớpHọcPhần, NgàyHoc
        }

        private void chkKiemTraDuLieuDaiHoc_Click(object sender, EventArgs e)
        {
            Program.KiemTraThoiKhoaBieuDaiHoc = !Program.KiemTraThoiKhoaBieuDaiHoc;
            chkKiemTraDuLieuDaiHoc.Image = Program.KiemTraThoiKhoaBieuDaiHoc ? Properties.Resources.CHECKBOX_YES : Properties.Resources.CHECKBOX_NO;
            FormResourcesViewer.Instance.NapDanhSachThoiKhoaBieu();
        }
    }
}
